package com.chunayev.numerology.gui.frame;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Collection;

import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;


import com.chunayev.numerology.domain.Chakra;
import com.chunayev.numerology.domain.Plan;
import com.chunayev.numerology.domain.PositionSummary;
import com.chunayev.numerology.gui.action.DeleteMiddlenameFromSetAction;
import com.chunayev.numerology.gui.action.DeleteNameFromSetAction;
import com.chunayev.numerology.gui.action.DeleteSurnameFromSetAction;
import com.chunayev.numerology.gui.action.DeleteTitileFromSetAction;
import com.chunayev.numerology.gui.action.SaveSummaryAction;
import com.chunayev.numerology.gui.list.EntityList;
import com.chunayev.numerology.util.Constants;
import com.chunayev.numerology.util.db.DBInitializer;
import com.sleepycat.je.DatabaseException;

/**
 * @author Sergey Chunayev
 */
public class SummaryFrame extends JFrame {
    
    /**
     * 
     */
    private static final long serialVersionUID = -4544279415704643031L;
    
    private final JLabel chakraLabel = initTopLabel();
    private final JLabel planLabel = initTopLabel();
    private final JLabel positionLabel = initTopLabel();
    
    private final EntityList middlenamesList = new EntityList();
    private final EntityList namesList = new EntityList();
    private final EntityList surnamesList = new EntityList();
    private final EntityList titlesList = new EntityList();
    
    private final EntityList[] lists = { middlenamesList, namesList,
            surnamesList, titlesList };
    
    private final JTextArea descriptionArea = new JTextArea(10, 10);
    
    private final SaveSummaryAction saveAction = new SaveSummaryAction();
    
    private PositionSummary positionSummary;
    private Chakra chakra;
    private Plan plan;
    
    /**
     * @throws DatabaseException
     */
    public SummaryFrame() throws DatabaseException {
        this(null);
    }
    
    /**
     * @throws DatabaseException
     */
    public SummaryFrame(final PositionSummary positionSummary)
            throws DatabaseException {
        super(Constants.RESOURCE_BUNDLE.getString("summary.frame.title"));
        
        addWindowListener(new WindowAdapter() {
            
            /*
             * (non-Javadoc)
             * @see
             * java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent
             * )
             */
            @Override
            public void windowClosing(final WindowEvent e) {
                super.windowClosing(e);
                descriptionArea.setText("");
            }
        });
        this.positionSummary = positionSummary;
        initProperties();
        initLayout();
        initLayoutValues();
    }
    
    /**
     * @return the descriptionArea
     */
    public JTextArea getDescriptionArea() {
        return this.descriptionArea;
    }
    
    /**
     * @return the positionSummary
     */
    public PositionSummary getPositionSummary() {
        return this.positionSummary;
    }
    
    /**
     * @param positionSummary
     *            the positionSummary to set
     * @throws DatabaseException
     */
    public void setPositionSummary(final PositionSummary positionSummary)
            throws DatabaseException {
        this.positionSummary = positionSummary;
        initProperties();
        initLayoutValues();
    }
    
    public void update(final EntityList invoker) {
        initLayoutValues();
    }
    
    private JComponent borderEmbrace(final EntityList c, final String titleKey,
            final Action listMenuAction) {
        c.setBorder(BorderFactory.createTitledBorder(Constants.RESOURCE_BUNDLE
                .getString(titleKey)));
        c.setListMenuAction(listMenuAction);
        c.setSummaryFrame(this);
        c.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        JScrollPane scrollPane = new JScrollPane(c);
        scrollPane.setPreferredSize(new Dimension(200, 100));
        return scrollPane;
    }
    
    private JComponent borderEmbrace(final JComponent c, final String titleKey) {
        c.setBorder(BorderFactory.createTitledBorder(Constants.RESOURCE_BUNDLE
                .getString(titleKey)));
        return c;
    }
    
    private void initLayout() {
        final Container c = getContentPane();
        
        final JPanel dataPanel = new JPanel(new BorderLayout());
        final JPanel informationPanel = new JPanel(new GridLayout(1, 3));
        informationPanel.setBackground(informationPanel.getBackground()
                .darker());
        informationPanel.add(positionLabel);
        informationPanel.add(planLabel);
        informationPanel.add(chakraLabel);
        dataPanel.add(informationPanel);
        c.add(dataPanel, BorderLayout.NORTH);
        final JPanel namesPanel = new JPanel(new GridLayout(1, 4));
        
        namesPanel.add(borderEmbrace(namesList,
                "summary.frame.names.border.label",
                new DeleteNameFromSetAction(namesList)));
        namesPanel.add(borderEmbrace(surnamesList,
                "summary.frame.surnames.border.label",
                new DeleteSurnameFromSetAction(surnamesList)));
        namesPanel.add(borderEmbrace(middlenamesList,
                "summary.frame.middlenames.border.label",
                new DeleteMiddlenameFromSetAction(middlenamesList)));
        namesPanel.add(borderEmbrace(titlesList,
                "summary.frame.titles.border.label",
                new DeleteTitileFromSetAction(titlesList)));
        
        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPane.add(namesPanel);
        
        final JPanel descriptionPanel = new JPanel(new BorderLayout());
        descriptionPanel.add(new JScrollPane(borderEmbrace(descriptionArea,
                "summary.frame.description.border.label")));
        splitPane.add(descriptionPanel);
        c.add(splitPane);
        
        final JPanel buttonPanel = new JPanel();
        final JButton saveButton = new JButton(saveAction);
        saveAction.setDescriptionArea(descriptionArea);
        buttonPanel.add(saveButton);
        c.add(buttonPanel, BorderLayout.SOUTH);
    }
    
    private void initLayoutValues() {
        if (positionSummary != null) {
            for (EntityList list : lists) {
                list.setPositionSummary(positionSummary);
            }
            
            positionLabel.setText(String.format("%d", positionSummary.getId()));
            planLabel.setText(Constants.RESOURCE_BUNDLE.getString(String
                    .format("table.column.plan.%s", plan.getName()
                            .toLowerCase())));
            planLabel.setForeground(Constants.COLORS[(int) (6 - plan.getId())]);
            chakraLabel
                    .setText(Constants.RESOURCE_BUNDLE.getString(String.format(
                            "table.column.%s", chakra.getName().toLowerCase())));
            chakraLabel.setForeground(Constants.COLORS[(int) chakra.getId()]);
            
            descriptionArea.setText(positionSummary.getDescription());
            
            namesList.setListData(toArray(positionSummary.getNames()));
            surnamesList.setListData(toArray(positionSummary.getSurnames()));
            middlenamesList.setListData(toArray(positionSummary
                    .getMiddlenames()));
            titlesList.setListData(toArray(positionSummary.getCompanyNames()));
            
            saveAction.setPositionSummary(positionSummary);
        }
    }
    
    private void initProperties() throws DatabaseException {
        if (positionSummary != null) {
            chakra = DBInitializer.CHAKRA_PRIMARY_INDEX.get(positionSummary
                    .getChakraId());
            plan = DBInitializer.PLAN_PRIMARY_INDEX.get(positionSummary
                    .getPlanId());
        }
    }
    
    private JLabel initTopLabel() {
        JLabel label = new JLabel();
        label.setHorizontalAlignment(JLabel.CENTER);
        label.setFont(label.getFont()
                .deriveFont(label.getFont().getSize() + 5f));
        return label;
    }
    
    private Object[] toArray(final Collection<?> c) {
        if (c == null) {
            return new Object[0];
        }
        
        return c.toArray();
    }
    
}
